package com.fast.develop.management.resource.compoment;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.fast.develop.core.io.ResourceManager;
import com.fast.develop.management.resource.schema.DomainFieldInitializedDataHandler;
import com.fast.develop.management.resource.schema.DomainInitializedDataHandler;
import com.fast.develop.management.resource.schema.InitializedDataHandler;
import com.fast.develop.management.resource.utils.SchemaFileUtil;
import com.fast.develop.meta.base.MetaConfiguration;
import com.fast.develop.meta.dm.MetaDomainConstant;
import org.json.JSONTokener;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;

/**
 * @author 莫寅
 * @createTime 2022-06-17 11:35
 * @desc：
 */
public class SchemaWriter {

    private ResourceManager resourceManager;

    private MetaConfiguration metaConfiguration;

    private Map<String, InitializedDataHandler> initializedDataHander = new HashMap();

    public SchemaWriter(MetaConfiguration metaConfiguration, ResourceManager resourceManager) {
        this.resourceManager = resourceManager;
        this.metaConfiguration = metaConfiguration;

        initializedDataHander.put(MetaDomainConstant.TYPE, new DomainInitializedDataHandler());
        initializedDataHander.put(MetaDomainConstant.Field_TYPE, new DomainFieldInitializedDataHandler());
    }

    public String getFullPath(String path){

        //是否有文件后缀，没有则拼接.json后缀路径
        if(!SchemaFileUtil.hasSuffix(path)){
            path += SchemaFileUtil.SCHEMA_SUFFIX;
        }

        return path;
    }

    private void writeFile(String metaType, String path, String value){
        //是否有Schema 节点路径，有则不创建文件
        if(SchemaFileUtil.isSchemaNodePath(path)){
            return;
        }

        //是否有文件后缀，没有则拼接.json后缀路径
        if(!SchemaFileUtil.hasSuffix(path)){
            path += SchemaFileUtil.SCHEMA_SUFFIX;
        }

        //创建文件数据为空则生成初始化数据
        if(StrUtil.isBlank(value)){
            value = getInitializedData(metaType, path);
        }

        //验证写入数据的格式
        validation(metaType, value);
        //生成.json的文件，并写入数据
        resourceManager.createFile(path, JSONUtil.formatJsonStr(value).getBytes());
    }

    /**
     * 写入Schema节点
     */
    private void writeSchemaNode(String metaType, String path, String value){
        String filePath = null;

        if(SchemaFileUtil.isSchemaNodePath(path)){
            //获取文件路径
            filePath = SchemaFileUtil.getFilePath(path);
        }

        String fileValue = StrUtil.utf8Str(resourceManager.read(filePath));
        JSONObject jsonObject = JSONUtil.parseObj(fileValue);
        String schemaType = SchemaFileUtil.getSchemaType(path);
        String nodeName = SchemaFileUtil.getSchemaNodeName(path);
        JSONArray jsonArray = jsonObject.getJSONArray(schemaType);

        if(jsonArray == null){
            //写入初始化节点
            writeInitializedData(metaType, path);
        }else{
            //获取匹配节点
            AtomicReference<JSONObject> selectNodeObject = new AtomicReference<>();
            String finalValue = value;
            jsonArray.stream().forEach(o -> {
                JSONObject nodeObject = (JSONObject)o;
                if(nodeObject.getStr("name").equals(nodeName)){
                    selectNodeObject.set(nodeObject);
                }
            });

            if(selectNodeObject.get() == null){
                //写入初始化节点
                writeInitializedData(metaType, path);
            }else{
                //给当前节点重新设置值
                selectNodeObject.get().clear();
                selectNodeObject.get().putAll(JSONUtil.parseObj(finalValue));


                //验证写入数据的格式
                validation(metaType, jsonObject.toString());
                //生成.json的文件，并写入数据
                resourceManager.createFile(filePath, JSONUtil.formatJsonStr(jsonObject.toString()).getBytes());
            }
        }
    }

    /**
     * 写入节点初始化数据
     * @param metaType
     * @param path
     */
    private void writeInitializedData(String metaType, String path){
        String filePath = null;

        if(SchemaFileUtil.isSchemaNodePath(path)){
            //获取文件路径
            filePath = SchemaFileUtil.getFilePath(path);
        }

        String fileValue = StrUtil.utf8Str(resourceManager.read(filePath));
        JSONObject jsonObject = JSONUtil.parseObj(fileValue);

        String schemaType = SchemaFileUtil.getSchemaType(path);

        JSONArray jsonArray = jsonObject.getJSONArray(schemaType);

        //没有内容
        if(jsonArray == null){
            jsonArray = new JSONArray();
            jsonObject.set(schemaType, jsonArray);
        }


        String value = getInitializedData(metaType, path);
        JSONObject initJSONObject = JSONUtil.parseObj(value);
        jsonArray.add(initJSONObject);


        //验证写入数据的格式
        validation(metaType, jsonObject.toString());
        //生成.json的文件，并写入数据
        resourceManager.createFile(filePath, JSONUtil.formatJsonStr(jsonObject.toString()).getBytes());
    }



    private String getInitializedData(String metaType, String path){
        InitializedDataHandler initializedDataHandler = initializedDataHander.get(metaType);
        return initializedDataHandler.getData(path);
    }


    /**
     * 写文件
     * 可写入company.json文件
     * 可写入company.json#/fields 对schema节点写入
     * @param metaType
     * @param path
     * @param value
     */
    public void write(String metaType, String path, String value){
        //是否Schema节点操作
        if(SchemaFileUtil.isSchemaNodePath(path)){
            //写入Schema节点数据
            writeSchemaNode(metaType, path, value);
        }
        //是文件路径则写入文件
        else{
            writeFile(metaType, path, value);
        }
    }


    public void enable(String metaType, String path){
        updateEnableStatus(metaType, path, true);
    }

    public void disable(String metaType, String path){
        updateEnableStatus(metaType, path, false);
    }

    public void updateEnableStatus(String metaType, String path, boolean status){
        String fileValue = StrUtil.utf8Str(resourceManager.read(path));
        JSONObject jsonObject = JSONUtil.parseObj(fileValue);
        jsonObject.set("enabled", status);

        //生成.json的文件，并写入数据
        resourceManager.createFile(path, JSONUtil.formatJsonStr(jsonObject.toString()).getBytes());
    }

    private void validation(String metaType, String schemaValue){
        org.json.JSONObject schemaJsonObject = new org.json.JSONObject(new JSONTokener(schemaValue));
        metaConfiguration.getMetaRegistor("domain_model").getSchemaReader().validation(schemaJsonObject);
    }

}
